package com.xiyuan.smartutils.xml.parser;

import com.xiyuan.smartutils.StrUtils;
import com.xiyuan.smartutils.constants.SignConstants;
import com.xiyuan.smartutils.xml.Xml;
import com.xiyuan.smartutils.xml.XmlParser;
import com.xiyuan.smartutils.xml.Xmls;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 哈唏表解析器，和对象解析器类似
 *
 * @version v1.1.2 @author lgz 2017-8-21 新建与整理
 */
public class MapParser implements XmlParser, SignConstants
{
    private Xml xmlMain;
    
    @Override
    public XmlParser set(Xml xmlMain)
    {
        this.xmlMain = xmlMain;
        return this;
    }
    
    @Override
    public String toStringInner(Object obj, String tagName, int tagLevel)
    {
        if (tagName == null)
            tagName = "xml";
        
        StringBuilder strb = new StringBuilder();
        StrUtils.addNewLine(strb);
        StrUtils.addTwoSpace(strb, tagLevel);
        Xmls.addTagBegin(strb, tagName);
        
        Map<?, ?> map = (Map<?, ?>)obj;
        for (Entry<?, ?> entry : map.entrySet())
        {
            String tag = String.valueOf(entry.getKey());
            Object value = entry.getValue();
            strb.append(xmlMain.toStringInner(value, tag, tagLevel+1));
        }
        
        StrUtils.addNewLine(strb);
        StrUtils.addTwoSpace(strb, tagLevel);
        Xmls.addTagEnd(strb, tagName);
        return strb.toString();
    }

    @Override
    public Object toObjectInner(Node node, Class<?> clazz, Class<?> generics)
    {
        Map map = newMap(clazz);
        if (map == null)
        {//不支持的类型
            return null;
        }
        
        if (node == null || generics == null)
        {//没有内容或没配置泛型返回空表
            return map;
        }
        
        NodeList childList = node.getChildNodes();
        for (int i=0;i<childList.getLength();i++)
        {
            Node child = childList.item(i);
            if (child.getNodeType() != Node.ELEMENT_NODE)
                continue;
            
            String key = child.getNodeName();
            map.put(key, xmlMain.toObjectInner(child, generics, null));
        }
        
        return map;
    }
    
    
    private static Map<String, Object> newMap(Class<?> cls)
    {
        Map<String, Object> map = null;
        if (cls == Map.class || cls == HashMap.class)
            return new HashMap<String, Object>();
        else if (cls == ConcurrentMap.class || cls == ConcurrentHashMap.class)
            return new ConcurrentHashMap<String, Object>();
        else if (cls == Hashtable.class)
            return new Hashtable<String, Object>();
        else if (cls == LinkedHashMap.class)
            return new LinkedHashMap<String, Object>();
        else if (cls == TreeMap.class)
            return new TreeMap<String, Object>();
        else// 不支持的类型
            return map;
    }
}
